/*******************************************************************************
 * This file is part of blueprint4j www.blueprint4j.org.
 * 
 *     blueprint4j is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU Lesser General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 * 
 *     blueprint4j is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU Lesser General Public License for more details.
 * 
 *     You should have received a copy of the GNU Lesser General Public License
 *     along with blueprint4j. If not, see <http://www.gnu.org/licenses/>.
 ******************************************************************************/
package blueprint4j.db;

import java.sql.*;
import java.util.*;

import blueprint4j.gui.db.*;
import blueprint4j.utils.*;


public class VectorField {
    private Vector store = new Vector();
    
    public VectorField() {}
    
    public VectorField(Field fields[]) {
        for (int i =0;i < fields.length;i++) {
            add(fields[i]);
        }
    }
    
    public Field get(int pos) {
        return (Field)store.get(pos);
    }
    
    public Field get(String name) {
        for (int i = 0;i < size();i++) {
            if (get(i).getName().equals(name)) {
                return get(i);
            }
        }
        return null;
    }
    
    public int indexOf(String name) {
        for (int i =0;i < size();i++) {
            if (get(i).getName().equals(name)) {
                return i;
            }
        }
        return -1;
    }
    
    public boolean contains(String name) {
        return indexOf(name) != -1;
    }
    
    public boolean contains(Field item) {
        return store.contains(item);
    }
    
    public void add(Field item) {
        store.add(item);
    }
    
    public void add(Field field[]) {
        for (int i = 0;i < field.length;i++){
            add(field[i]);
        }
    }
    
    public int add(VectorField field) {
        for (int i = 0;i < field.size();i++){
            add(field.get(i));
        }
        return field.size();
    }
    
    public boolean remove(Field item) {
        return store.remove(item);
    }
    
    public Field remove(int pos) {
        return (Field) store.remove(pos);
    }
    
    public int size() {
        return store.size();
    }
    
    public void removeAll() {
        store.removeAllElements();
    }
    
    public VectorFieldForeignKey getFieldForeignKey() {
        VectorFieldForeignKey vffk = new VectorFieldForeignKey();
        for (int i = 0;i < size();i++) {
            if (get(i) instanceof FieldForeignKey) {
                vffk.add((FieldForeignKey)get(i));
            }
        }
        return vffk;
    }
    
    /**
     * This will locate and return the local field
     */
    public Field map(Field field) {
        for (int i =0;i < size();i++) {
            if (get(i).getName().equals(field.getName())) {
                return get(i);
            }
        }
        return null;
    }
    
    public Field[] toArray() {
        Field field[] = new Field[size()];
        for (int i =0;i < size();i++) {
            field[i]= get(i);
        }
        return field;
    }
    
    public String toString() {
        return toString(",");
    }
    
    public String toString(String delimeter) {
        StringBuffer combined=new StringBuffer("");
        for (int t=0;t<size();t++) {
            if (t>0) {
                combined.append(delimeter);
            }
            if (get(t) != null) {
                combined.append(get(t).toString());
            }
        }
        return combined.toString();
    }
    
    public boolean equals(VectorField field) {
        if (field.size() != size()) {
            return false;
        }
        for (int i=0;i < size();i++) {
            if (!get(i).getName().equals(field.get(i).getName())) {
                return false;
            }
        }
        return true;
    }
    
    
    public VectorField getNameField() {
        VectorField vf = new VectorField();
        for (int i = 0;i < size();i++) {
            if (get(i).isNameField()) {
                vf.add(get(i));
            }
        }
        if (vf.size() == 0) {
            for (int i = 0;i< size();i++) {
                if (get(i).isKey()) {
                    vf.add(get(i));
                }
            }
        }
        return vf;
    }
    
    public VectorString getNames() {
        VectorString store =new VectorString();
        for (int i=0;i < size();i++) {
            store.add(get(i).getName());
        }
        return store;
    }
    
    public VectorString getDescriptions() {
        VectorString store =new VectorString();
        for (int i=0;i < size();i++) {
            store.add(get(i).getDescription());
        }
        return store;
    }
    
    public Object[] getValue() throws DataException {
        Object data[] = new Object[size()];
        for(int i =0;i <size();i++) {
            data[i] = get(i).getObject();
        }
        return data;
    }
    
    public int[] getColumnWidth() {
        int width[] = new int[size()];
        for (int i =0;i < size();i++) {
            if (get(i).getLength() == 0) {
                width[i] = 50;
            } else {
                width[i] = get(i).getLength();
            }
        }
        return width;
    }
    
//    private int getFieldLength(Field field) {
//        int len = 0;
//        if (field instanceof FieldText) {
//            len = 480;
//        } else if (field instanceof FieldString) {
//            len = ((FieldString)field).getLength()*4;
//        } else {
//            len = 30;
//        }
//        if (len < new javax.swing.JLabel(field.getDescription()).getMinimumSize().getWidth()*2) {
//            len = (int) new javax.swing.JLabel(field.getDescription()).getMinimumSize().getWidth()*2;
//        }
//        return len;
//    }
    
//    public EntityPanelFieldBinder[] toEntityPanelFieldBinder() {
//        EntityPanelFieldBinder panels[] = new EntityPanelFieldBinder[size()];
//        for (int i =0;i < size();i++) {
//            panels[i] =
//                    new DefaultFieldBinder(
//                    get(i),
//                    getFieldLength(get(i))
//                    );
//        }
//        return panels;
//    }
    
    public boolean isChanged() {
        for(int i = 0;i <size();i++) {
            if (get(i).isChanged()) {
                return true;
            }
        }
        return false;
    }
    
    public boolean isChangedExcludeBlob() {
        for(int i = 0;i <size();i++) {
            if (get(i).isChanged() && !(get(i) instanceof FieldBlob)) {
                return true;
            }
        }
        return false;	}
    
    public VectorFieldBlob getChangedBlob() {
        VectorFieldBlob blobs = new VectorFieldBlob();
        for (int i = 0;i < size();i++) {
            if (get(i) instanceof FieldBlob && get(i).isChanged()) {
                blobs.add((FieldBlob)get(i));
            }
        }
        return blobs;
    }
    
    /**
     * Returns a list of all fields that are non virtual and not load on demand
     */
    public VectorField getSelectable() {
        VectorField fields = new VectorField();
        for (int i =0;i < size();i++) {
            if (!get(i).isFieldVirtual() && get(i).shouldLoad() && (get(i).getEntity().loadOnDemandField() || !get(i).isLoadOnDemand())) {
                fields.add(get(i));
            }
        }
        return fields;
    }
    
    /**
     * Returns all fields filtered on the filter
     * A filter of -1 means all fields and will return all fields
     */
    public VectorField getFiltered(int filter,boolean negate) {
        VectorField vf = new VectorField();
        for (int i = 0;i < size();i++) {
            if (filter == -1) {
                vf.add(get(i));
            } else {
                if (
                        (!negate && get(i).isNot(filter)) ||
                        (negate && get(i).is(filter))
                        ) {
                    vf.add(get(i));
                }
            }
        }
        return vf;
    }
    
    public VectorField getFiltered(VectorField vfield) {
        VectorField vf = new VectorField();
        for (int i = 0;i < size();i++) {
            if (vfield.contains(get(i).getName())) {
                vf.add(get(i));
            }
        }
        return vf;
    }
    
    public VectorString getSerializable() throws BindException {
        VectorString vs = new VectorString();
        for (int i = 0;i < size();i++) {
            vs.add(get(i).getSerializable());
        }
        return vs;
    }
    
    public void setSerializable(VectorString stream) throws BindException {
        for (int i = 0;i < size();i++) {
            get(i).setSerializable(stream.get(i));
        }
    }
    
    /**
     * Move all fields to entity
     * Does not move duplicates
     */
    public void copyTo(Entity entity) {
        for (int i =0;i < size();i++) {
            if (!entity.getFields().contains(get(i).getName())) {
                get(i).newInstance(entity);
            }
        }
    }
    
}

